/**
 ******************************************************************************
 * @file	include/stm32-spi.h
 * @brief	TR700-STM32 spi 通信
 *
 * 详细协议格式参看 《TR700-RM》
 * https://git.oschina.net/glinklib/tr700-stm32/doc/TR700-RM.md
 *
 * Copyright (C) [2017] <桂林聚联科技有限公司, Inc.> All Rights Reserved.
 *
 *
 * @section Platform
 *	-# linux-2.6
 * @section Library
 *	-# null
 *
 * @section Depend
 *	-# spi_mxs.ko
 *	-# spidev.ko
 *	-# libpthread.so
 *
 * - 2017-6-22,MenglongWu,MenglongWoo@aliyun.com
 */
#ifndef _STM32_SPI_H_
#define _STM32_SPI_H_
#include <autoconfig.h>
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>

#include "spi-tr700-hdr.h"

#define BIT_DEF  0x01
#define BIT_TX   0x02
#define BIT_RX   0x04
#define BIT_BUSY 0x08

#if CONFIG_USE_PRINTL
#define STM32SPI_DBG_LEVEL             (LEVEL_ID(LEVEL_GROUP - 1, SUB_GROUP - 2))
#define STM32SPI_DBG_TX                (STM32SPI_DBG_LEVEL & BIT_TX)
#define STM32SPI_DBG_RX                (STM32SPI_DBG_LEVEL & BIT_RX)
#define STM32SPI_DBG_BUSY              (STM32SPI_DBG_LEVEL & BIT_BUSY)


#define EN_STM32SPI_DBG_LEVEL(en)      (STM32SPI_DBG_LEVEL |= (en))
#define DISABLE_STM32SPI_DBG_LEVEL(en) (PRINT_OTDR_DATA &= ~(en))
#else
#define STM32SPI_DBG_LEVEL 1
#define PRINT_OTDR_DATA    1

#define STM32SPI_DBG_TX    1
#define STM32SPI_DBG_RX    1
#define STM32SPI_DBG_BUSY  1


#define EN_STM32SPI_DBG_LEVEL(en)
#define EN_PRINT_OTDR_DATA(en)
#define EN_OTDR_PRINTL(en)
#endif


/** @defgroup stm32_interface
 * @{
 */

struct wave_list
{
    int ch;
    int wave;
};

/**
 * @brief	stm32 设备描述
 */
struct stm32_spi_dev
{
    int              fd;    ///< 设备FD，正常 stm32_open 后返回
    unsigned long    pid;   ///< 设备id，正常 stm32_open 后返回
    char            *desc;  ///< 设备描述，，正常 stm32_open 后返回
    struct wave_list wl[3];
    pthread_mutex_t  mutex;  ///< 互斥锁
                             // void *private;
};


/**
 * @brief	打开TR700-STM32设备的SPI总线
 * @param	device 总线名，如/dev/spidev2.0
 * @param	dev    返回设备描述
 * @param	ispeed 总线速度，100000~500000 （100KHz~500KHz）
 * @retval	0 成功
 * @remarks
 * @see
 */

int stm_open(char *device, struct stm32_spi_dev **dev, unsigned long ispeed);
/**
 * @brief	关闭TR700-STM32设备总线
 * @retval	0 成功
 */

int stm_close(struct stm32_spi_dev *dev);
/**
 * @brief	设置光源输出功率
 * @param	val 参数结构
 * @retval	null
 * @remarks
 * @see
 */
int stm_setls(struct stm32_spi_dev *dev, struct tr700_setls_tx *val);
int stm_setls_dbg(struct stm32_spi_dev *dev, struct tr700_setls_dbg_tx *val);
int stm_getls_dbg(struct stm32_spi_dev *dev, struct tr700_getls_dbg *val);
/**
 * @brief	设置TR700-STM32环境变量
 * @param	env 环境变量名
 * @param	val 环境变量值，不允许超过PRE_ENV_LEN环境变量最大值
 * @retval	0 成功
 */

int stm_setenv(struct stm32_spi_dev *dev, char *env, char *val);

/**
 * @brief	获取TR700-STM32环境变量
 * @param	env 环境变量名
 * @param	val 环境变量值，PRE_ENV_LEN环境变量最大值
 * @retval	0 成功
 */
int stm_getenv(struct stm32_spi_dev *dev, char *env, char (*val)[PRE_ENV_LEN]);
/**
 * @brief	保存TR700-STM32环境变量
 * @remarks	0 成功
 */

int stm_saveenv(struct stm32_spi_dev *dev);


/**
 * @brief	TODO 设置光功率，以后命名改成 stm_setopm
 * @param	level 改成参考波长 ref_wave
 * @retval	0 成功
 */

int stm_setopm_param(struct stm32_spi_dev *dev, int level);

int stm_setopm(struct stm32_spi_dev *dev, struct tr700_setopm *val);

/**
 * @brief	读取TR700-STM32光功率值
 * @param	val 光功率返回值
 * @retval	0 成功
 */

int stm_getopm(struct stm32_spi_dev *dev, struct tr700_getopm *val);
int stm_alive(struct stm32_spi_dev *dev);
int stm_debug(struct stm32_spi_dev *dev, int dbg);

int stm_getopm_dbg(struct stm32_spi_dev *dev, struct tr700_getopm_dbg *val);


/******************************************************************************
 * 非必须接口
 */

/**
 * @brief	检索TR700-STM32光源设备有几个通道，各通道对应波长
 * @param	list  通道列表
 * @param	count 返回最大通道数
 * @retval	n     返回具体拥有多少个通道上焊接有激光器
 */

int stm_ls_wavelist(struct stm32_spi_dev *dev, struct wave_list *list, int count);

/**
 * @brief	通过通道号查询波长
 *
 * 			注意，这个接口限制，必须每个通道对应不同波长，否则返回第一个匹配的
 *
 * @param	ch 查询通道编号
 * @retval	0  该通道没有激光器
 * @retval	>0 该通道对应激光器波长
 * @remarks	必须先调用 stm_ls_wavelist
 */

int stm_ch2wave(struct stm32_spi_dev *dev, int ch);

/**
 * @brief	通过波长查询通道号
 *
 * 			注意，这个接口限制，必须每个通道对应不同波长，否则返回第一个匹配的
 *
 * @param	wave 激光器波长
 * @retval	0  没有找到该波长
 * @retval	>0 该波长对应通道
 * @remarks	必须先调用 stm_ls_wavelist
 */
int stm_wave2ch(struct stm32_spi_dev *dev, int wave);

/*
 * End 非必须接口
 *****************************************************************************/

#endif  // INCLUDE_STM32_SPI_H_
